package com.zhang.boot.core.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.zhang.boot.core.constants.ApiConstant;
import com.zhang.boot.core.constants.SecurityConstant;
import com.zhang.boot.core.entity.Role;
import com.zhang.boot.core.util.ServletUtils;
import com.zhang.boot.core.vo.LoginUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

@Service("ss")
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
@Slf4j
public class PermissionService {

    private final TokenService tokenService;

    /**
     * 验证用户是否具备某权限
     *
     * @param permission
     * @return
     */
    public boolean hasPermission(String permission) {
        if (StrUtil.isEmpty(permission)) {
            return false;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (loginUser == null || CollUtil.isEmpty(loginUser.getPermissions())) {
            return false;
        }
        return hasPermission(loginUser.getPermissions(), permission);
    }

    /**
     * 验证用户是否不具备某权限
     *
     * @param permission
     * @return
     */
    public boolean lackPermission(String permission) {
        return !hasPermission(permission);
    }

    /**
     * 验证用户是否具有以下任意一个权限
     *
     * @param permissions
     * @return
     */
    public boolean hasAnyPermission(String permissions) {
        if (StrUtil.isEmpty(permissions)) {
            return false;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (loginUser == null || CollUtil.isEmpty(loginUser.getPermissions())) {
            return false;
        }
        Set<String> permissionSet = loginUser.getPermissions();
        String[] checkPermissions = permissions.split(ApiConstant.DELIMITER);
        for (String checkPermission : checkPermissions) {
            if (checkPermission != null && hasPermission(permissionSet, checkPermission)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断用户是否具有某个角色
     *
     * @param role
     * @return
     */
    public boolean hasRole(String role) {
        if (StrUtil.isEmpty(role)) {
            return false;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (loginUser == null || CollUtil.isEmpty(loginUser.getUser().getRoles())) {
            return false;
        }
        List<Role> roles = loginUser.getUser().getRoles();
        for (Role roleTemp : roles) {
            String roleKey = roleTemp.getRoleKey();
            if (ApiConstant.ADMIN.equals(roleKey) || role.equals(roleKey)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 验证用户是否不具备某角色
     *
     * @param role
     * @return
     */
    public boolean lackRole(String role) {
        return !hasRole(role);
    }

    /**
     * 验证用户是否具有以下任意一个角色
     * @param role
     * @return
     */
    public boolean hasAnyRoles(String role) {
        if (StrUtil.isEmpty(role)) {
            return false;
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (loginUser == null || CollUtil.isEmpty(loginUser.getUser().getRoles())) {
            return false;
        }
        List<Role> rolesList = loginUser.getUser().getRoles();
        String[] roles = role.split(ApiConstant.DELIMITER);
        for (String roleTemp : roles) {
            if (hasRole(role)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否包含权限
     *
     * @param permissions 权限列表
     * @param permission  权限字符串
     * @return
     */
    public boolean hasPermission(Set<String> permissions, String permission) {
        return permissions.contains(SecurityConstant.ALL_PERMISSION) || permissions.contains(permission);
    }


}
